home *** CD-ROM | disk | FTP | other *** search
/ FishMarket 1.0 / FishMarket v1.0.iso / fishies / 551-575 / disk_551 / toolmanager / source / config.c < prev    next >
C/C++ Source or Header  |  1992-05-06  |  17KB  |  550 lines

  1. /*
  2.  * config.c   V1.5
  3.  *
  4.  * configuration file handling
  5.  *
  6.  * (c) 1991 by Stefan Becker
  7.  *
  8.  */
  9. #include "ToolManager.h"
  10.  
  11. /* Tool type keywords in the configuration file, must end with a ':'!! */
  12. static char IconKey[]="ICON:";
  13. static char DockKey[]="DOCK:";
  14. static char DummyKey[]="DUMMY:";
  15. static char CLIKey[]="CLI:";
  16. static char WBKey[]="WB:";
  17. #define CONFIGBLOCKEND '#'
  18.  
  19. /* Config entry keywords */
  20. static char AssignKey[]=" = ";
  21. char AliasKey[]="Alias   ";
  22. char RealKey[]="RealName";
  23. static char DirKey[]="WorkDir ";
  24. static char PathKey[]="Path    ";
  25. static char OFileKey[]="OutFile ";
  26. char MenuKey[]="Menu    ";
  27. char HotKKey[]="HotKey  ";
  28. char StackKey[]="Stack   ";
  29. static char ArgsKey[]="Args    ";
  30. static char OutputKey[]="Output  ";
  31. static char WBFrontKey[]="WBFront ";
  32. static char NameKey[]="IconName";
  33. static char ITypeKey[]="IconType";
  34. char IFileKey[]="IconFile";
  35. static char IPosKey[]="IconPos ";
  36. static char DockOnKey[]="ShowDock";
  37. static char SIconKey[]="SameIcon";
  38. static char DTypeKey[]="DockType";
  39. char DFileKey[]="DockFile";
  40. static char OffKey[]="OFF";
  41. static char OnKey[]="ON";
  42. char BrushKey[]="Brush";
  43. char DObjKey[]="Icon";
  44.  
  45. /* Data for syntax error requester */
  46. static struct EasyStruct SyntaxErrES={sizeof(struct EasyStruct),0,MyName,
  47.                                       "Syntax error in configuration file\n"\
  48.                                       "%s, line %ld\n'%s'","Ok"};
  49.  
  50. /* External variables for Dock */
  51. extern UWORD DockXPos,DockYPos;
  52. extern UWORD DockXSize,DockYSize;
  53. extern BOOL DockVertical;
  54. extern BOOL DockToBack;
  55.  
  56. /* Set the name of the config file */
  57. void SetConfigFileName(char *s)
  58. {
  59.  if (ConfigName) free(ConfigName);
  60.  ConfigName=strdup(s);
  61. }
  62.  
  63. /* Init a config block struct */
  64. void InitConfigBlock(struct ConfigBlock *cb)
  65. {
  66.  cb->cb_Type=255;
  67.  cb->cb_Flags=TNFLAGS_MENU|TNFLAGS_DOBJ|TNFLAGS_DDOB;
  68.  cb->cb_Stack=STACKMIN;
  69.  cb->cb_IconX=NO_ICON_POSITION;
  70.  cb->cb_IconY=NO_ICON_POSITION;
  71.  cb->cb_Alias[0]='\0';
  72.  cb->cb_Alias[BUFLEN-1]='\0';
  73.  cb->cb_RealName[0]='\0';
  74.  cb->cb_RealName[BUFLEN-1]='\0';
  75.  cb->cb_WorkDir[0]='\0';
  76.  cb->cb_WorkDir[BUFLEN-1]='\0';
  77.  cb->cb_Path[0]='\0';
  78.  cb->cb_Path[BUFLEN-1]='\0';
  79.  cb->cb_OutFile[0]='\0';
  80.  cb->cb_OutFile[BUFLEN-1]='\0';
  81.  cb->cb_HotKey[0]='\0';
  82.  cb->cb_HotKey[BUFLEN-1]='\0';
  83.  cb->cb_IconFile[0]='\0';
  84.  cb->cb_IconFile[BUFLEN-1]='\0';
  85.  cb->cb_DockFile[0]='\0';
  86.  cb->cb_DockFile[BUFLEN-1]='\0';
  87. }
  88.  
  89. /* Read one config file entry */
  90. static void ReadConfigBlock(FILE *fh, struct ConfigBlock *cb, char *name,
  91.                             int *lines, struct Window *w)
  92. {
  93.  register char *cp=cb->cb_TempLine;
  94.  
  95.  while (!feof(fh)) /* if not end of file, read one line into buffer */
  96.   {
  97.    (*lines)++;
  98.  
  99.    if (fgets(cp,BUFLEN+20,fh) && (strlen(cp)>1)) /* Skip empty lines */
  100.     if (*cp==CONFIGBLOCKEND) return;             /* End of entry reached */
  101.     else
  102.      {
  103.       register char *parm;
  104.  
  105.       /* Remove trailing newline */
  106.       if (cp[strlen(cp)-1]=='\n') cp[strlen(cp)-1]='\0';
  107.  
  108.       /* Scan line for '=' */
  109.       parm=strchr(cp,'=');
  110.  
  111.       /* Skip white space */
  112.       if (parm)
  113.        {
  114.         parm++;
  115.         while (*parm && isspace(*parm)) parm++;
  116.        }
  117.  
  118.       /* Valid parameter? */
  119.       if (!parm && !*parm)
  120.        {
  121.         /* No --> Syntax error */
  122.         EasyRequest(w,&SyntaxErrES,NULL,name,*lines,cp);
  123.  
  124.         /* Next line */
  125.         continue;
  126.        }
  127.  
  128.       /* Extract parameter value */
  129.       if (!strnicmp(cp,AliasKey,5))                  /* Alias    = <string> */
  130.        strncpy(cb->cb_Alias,parm,BUFLEN-1);
  131.       else if (!strnicmp(cp,RealKey,8))              /* RealName = <string> */
  132.             strncpy(cb->cb_RealName,parm,BUFLEN-1);
  133.       else if (!strnicmp(cp,DirKey,7))               /* WorkDir  = <string> */
  134.             strncpy(cb->cb_WorkDir,parm,BUFLEN-1);
  135.       else if (!strnicmp(cp,PathKey,4))              /* Path     = <string> */
  136.             {
  137.              if (cb->cb_Type==TNTYPE_CLI) /* CLI tools only! */
  138.               strncpy(cb->cb_Path,parm,BUFLEN-1);
  139.             }
  140.       else if (!strnicmp(cp,OFileKey,7))             /* OutFile  = <string> */
  141.             {
  142.              if (cb->cb_Type==TNTYPE_CLI) /* CLI tools only! */
  143.               {
  144.                cb->cb_Flags|=TNFLAGS_COUT;           /* Set output flag */
  145.                strncpy(cb->cb_OutFile,parm,BUFLEN-1);
  146.               }
  147.             }
  148.       else if (!strnicmp(cp,HotKKey,6))              /* HotKey   = <string> */
  149.             strncpy(cb->cb_HotKey,parm,BUFLEN-1);
  150.       else if (!strnicmp(cp,IFileKey,8))             /* IconFile = <string> */
  151.             {
  152.              cb->cb_Flags|=TNFLAGS_ICON;             /* Set icon flag */
  153.              strncpy(cb->cb_IconFile,parm,BUFLEN-1);
  154.             }
  155.       else if (!strnicmp(cp,StackKey,5))             /* Stack    = <number> */
  156.             {
  157.              char *cp1;
  158.  
  159.              cb->cb_Stack=strtol(parm,&cp1,10);
  160.             }
  161.       else if (!strnicmp(cp,ArgsKey,4))              /* Args     = OFF */
  162.             {
  163.              if (!stricmp(parm,OffKey)) cb->cb_Flags|=TNFLAGS_NARG;
  164.             }
  165.       else if (!strnicmp(cp,OutputKey,6))            /* Output   = ON */
  166.             {
  167.              if (!stricmp(parm,OnKey) && (cb->cb_Type==TNTYPE_CLI))
  168.               cb->cb_Flags|=TNFLAGS_COUT;            /* Set output flag */
  169.             }
  170.       else if (!strnicmp(cp,WBFrontKey,7))           /* WBFront  = ON */
  171.             {
  172.              if (!stricmp(parm,OnKey)) cb->cb_Flags|=TNFLAGS_WBTF;
  173.             }
  174.       else if (!strnicmp(cp,MenuKey,4))              /* Menu     = OFF */
  175.             {
  176.              if (!stricmp(parm,OffKey)) cb->cb_Flags&=~TNFLAGS_MENU;
  177.             }
  178.       else if (!strnicmp(cp,NameKey,6))              /* Name     = OFF */
  179.             {
  180.              cb->cb_Flags|=TNFLAGS_ICON;             /* Set icon flag */
  181.              if (!stricmp(parm,OffKey)) cb->cb_Flags|=TNFLAGS_NNAM;
  182.             }
  183.       else if (!strnicmp(cp,ITypeKey,8))             /* IconType = Brush */
  184.             {
  185.              cb->cb_Flags|=TNFLAGS_ICON;             /* Set icon flag */
  186.              if (!stricmp(parm,BrushKey)) cb->cb_Flags&=~TNFLAGS_DOBJ;
  187.             }
  188.       else if (!strnicmp(cp,IPosKey,7))              /* IconPos  = <x,y> */
  189.             {
  190.              char *cp1;
  191.  
  192.              cb->cb_Flags|=TNFLAGS_ICON;             /* Set icon flag */
  193.              cb->cb_IconX=strtol(parm,&cp1,10);
  194.              if (cp1) cb->cb_IconY=strtol(cp1+1,&cp1,10);
  195.             }
  196.       else if (!strnicmp(cp,DockOnKey,8))            /* Dock     = ON */
  197.             {
  198.              if (!stricmp(parm,OnKey)) cb->cb_Flags|=TNFLAGS_DOCK;
  199.             }
  200.       else if (!strnicmp(cp,SIconKey,8))             /* SameIcon = ON */
  201.             {
  202.              cb->cb_Flags|=TNFLAGS_DOCK;             /* Set dock flag */
  203.              if (!stricmp(parm,OnKey)) cb->cb_Flags|=TNFLAGS_SICN;
  204.             }
  205.       else if (!strnicmp(cp,DTypeKey,8))             /* DockType = Brush */
  206.             {
  207.              cb->cb_Flags|=TNFLAGS_DOCK;             /* Set dock flag */
  208.              if (!stricmp(parm,BrushKey)) cb->cb_Flags&=~TNFLAGS_DDOB;
  209.             }
  210.       else if (!strnicmp(cp,DFileKey,8))             /* DockFile = <string> */
  211.             {
  212.              cb->cb_Flags|=TNFLAGS_DOCK;             /* Set dock flag */
  213.              cb->cb_Flags&=~TNFLAGS_SICN;            /* Clear same image flag */
  214.              strncpy(cb->cb_DockFile,parm,BUFLEN-1);
  215.             }
  216.       else                                   /* Comment or unknown keyword */
  217.        if (*cp!=';')
  218.         {
  219.          cp[strlen(cp)-1]='\0'; /* remove trailing \n */
  220.          EasyRequest(w,&SyntaxErrES,NULL,name,*lines,cp);
  221.         }
  222.      }
  223.   }
  224. }
  225.  
  226. /* Read configuration file */
  227. void ReadConfigFile(char *name, BOOL complete)
  228. {
  229.  struct ConfigBlock *cb;  /* Memory block for one config file entry */
  230.  FILE *fh;                /* Filehandle for config file */
  231.  int lines=0;             /* Line counter */
  232.  struct Screen *pubsc;
  233.  struct Window *w=NULL;   /* Pointer to Window for EasyRequest() */
  234.  
  235.  if (pubsc=LockPubScreen(WBScreenName))
  236.   w=pubsc->FirstWindow;
  237.  
  238.  if (cb=malloc(sizeof(struct ConfigBlock)))  /* Get memory */
  239.   {
  240.    register char *cp=cb->cb_TempLine;
  241.  
  242.    if (name && (fh=fopen(name,"r"))) /* Scan config file */
  243.     {
  244.      while (!feof(fh)) /* if not end of file, read one line into buffer */
  245.       {
  246.        lines++;
  247.  
  248.        if (fgets(cp,BUFLEN,fh) && (strlen(cp)>1)) /* Skip empty lines */
  249.         {
  250.          InitConfigBlock(cb);
  251.  
  252.          /* Extract tool type */
  253.          if (!strnicmp(cp,IconKey,sizeof(IconKey)-1))        /* ICON: */
  254.           {
  255.            if (complete)
  256.             {
  257.              char *cp1;
  258.  
  259.              /* ICON: <num>,<num> */
  260.              IconXPos=strtol(cp+sizeof(IconKey)-1,&cp1,10);
  261.              if (cp1) IconYPos=strtol(cp1+1,&cp1,10);
  262.             }
  263.           }
  264.          else if (!strnicmp(cp,DockKey,sizeof(DockKey)-1))   /* DOCK: */
  265.           {
  266.            if (complete)
  267.             {
  268.              char *cp1;
  269.  
  270.              /* DOCK: <num>,<num>,<num>,<num>,(H|V)(F|B) */
  271.              DockXPos=strtol(cp+sizeof(DockKey)-1,&cp1,10);
  272.              if (cp1) DockYPos=strtol(cp1+1,&cp1,10);
  273.              if (cp1) DockXSize=strtol(cp1+1,&cp1,10)+1;
  274.              if (DockXSize<=0) DockXSize=41;
  275.              if (cp1) DockYSize=strtol(cp1+1,&cp1,10)+1;
  276.              if (DockYSize<=0) DockYSize=41;
  277.              if (cp1) DockVertical=(cp1[1]=='V');
  278.              if (cp1) DockToBack=(cp1[2]=='B');
  279.             }
  280.           }
  281.          else if (!strnicmp(cp,DummyKey,sizeof(DummyKey)-1)) /* DUMMY: */
  282.           cb->cb_Type=TNTYPE_DUMMY;
  283.          else if (!strnicmp(cp,CLIKey,sizeof(CLIKey)-1))     /* CLI: */
  284.           cb->cb_Type=TNTYPE_CLI;
  285.          else if (!strnicmp(cp,WBKey,sizeof(WBKey)-1))       /* WB: */
  286.           cb->cb_Type=TNTYPE_WB;
  287.          else if (*cp!=';')              /* Comment or Syntax error */
  288.           {
  289.            /* Syntax error, display error requester */
  290.            cp[strlen(cp)-1]='\0'; /* remove trailing \n */
  291.            EasyRequest(w,&SyntaxErrES,NULL,name,lines,cp);
  292.  
  293.            /* Try to skip to end of current block */
  294.            while (!feof(fh))
  295.             {
  296.              lines++;
  297.              fgets(cp,BUFLEN,fh);
  298.              if (*cp==CONFIGBLOCKEND) break;
  299.             }
  300.           }
  301.  
  302.          /* Does a valid config block follow? */
  303.          if (cb->cb_Type!=255)
  304.           {
  305.            /* Read in one config file entry */
  306.            ReadConfigBlock(fh,cb,name,&lines,w);
  307.  
  308.            /* Special check for empty dummy tool entries */
  309.            if ((cb->cb_Type==TNTYPE_DUMMY) && (cb->cb_Alias[0]=='\0') &&
  310.                (cb->cb_RealName[0]=='\0'))
  311.             strcpy(cb->cb_Alias," ");
  312.  
  313.            /* Add tool */
  314.            AddToolNode(cb,StartupCD);
  315.           }
  316.         }
  317.       }
  318.      fclose(fh);
  319.     }
  320.  
  321.    free(cb);
  322.   }
  323.  
  324.  if (pubsc) UnlockPubScreen(NULL,pubsc);
  325. }
  326.  
  327. /* Tiny long to string conversion routine */
  328. static void ltoa(char *s, long n)
  329. {
  330.  long i=1000000000;     /* Divisor */
  331.  BOOL inumber=FALSE;    /* Flag */
  332.  
  333.  if (n==-2147483648)    /* Handle special case 2^31*/
  334.   {
  335.    strcpy(s,"-2147483648");
  336.    return;
  337.   }
  338.  
  339.  if (n<0)               /* Handle negativ numbers */
  340.   {
  341.    n=-n;
  342.    *s++='-';
  343.   }
  344.  
  345.  if (n==0) *s++='0';    /* Zero is a special case */
  346.  else while (i)         /* Every other numer goes here */
  347.        {
  348.         *s=n/i+'0';     /* Retrieve leading digit */
  349.         if (*s!='0') inumber=TRUE; /* Suppress leading zero's */
  350.         if (inumber) s++;
  351.         n%=i;           /* Remove digit from number */
  352.         i/=10;          /* next divisor */
  353.        }
  354.  
  355.  *s='\0';               /* Append string terminator */
  356. }
  357.  
  358. /* Write one parameter keyword */
  359. static void WriteParamKey(char *cp, FILE *fh)
  360. {
  361.  fputs(cp,fh);        /* Write keyword */
  362.  fputs(AssignKey,fh); /* Write " = " */
  363. }
  364.  
  365. /* Write one complete config line */
  366. static void WriteConfigLine(char *key, char *parm, FILE *fh)
  367. {
  368.  WriteParamKey(key,fh); /* Write keyword */
  369.  fputs(parm,fh);        /* Write parameter */
  370.  fputc('\n',fh);        /* Write newline */
  371. }
  372.  
  373. /* Write configuration file */
  374. BOOL WriteConfigFile(struct Window *w, BOOL noreq)
  375. {
  376.  BOOL error=FALSE;
  377.  BOOL rc=TRUE;     /* Means user pressed cancel */
  378.  char *cp;
  379.  char number[20];
  380.  
  381.  /* ConfigName was NOT set because of low mem situation --> break */
  382.  if (!ConfigName) goto wce0;
  383.  
  384.  /* Show file requester */
  385.  cp=ConfigName;
  386.  if (noreq || !ShowFileRequester(w,"Save Configuration",&cp,FREQ_SAVE))
  387.   {
  388.    /* User selected a file */
  389.    FILE *fh;
  390.  
  391.    /* Set new name */
  392.    if (!noreq) SetConfigFileName(cp);
  393.  
  394.    if (fh=fopen(cp,"w"))             /* Open config file */
  395.     {
  396.      register struct ToolNode *tn;
  397.  
  398.      /* Write icon position line */
  399.      if ((IconXPos!=NO_ICON_POSITION) || (IconYPos!=NO_ICON_POSITION))
  400.       {
  401.        fputs(IconKey,fh);
  402.        ltoa(number,IconXPos);
  403.        fputs(number,fh);
  404.        fputc(',',fh);
  405.        ltoa(number,IconYPos);
  406.        fputs(number,fh);
  407.        fputc('\n',fh);
  408.       }
  409.  
  410.      /* Write dock window position line */
  411.      fputs(DockKey,fh);
  412.      ltoa(number,DockXPos);
  413.      fputs(number,fh);
  414.      fputc(',',fh);
  415.      ltoa(number,DockYPos);
  416.      fputs(number,fh);
  417.      fputc(',',fh);
  418.      ltoa(number,DockXSize-1);
  419.      fputs(number,fh);
  420.      fputc(',',fh);
  421.      ltoa(number,DockYSize-1);
  422.      fputs(number,fh);
  423.      fputc(',',fh);
  424.      if (DockVertical)
  425.       fputc('V',fh);
  426.      else
  427.       fputc('H',fh);
  428.      if (DockToBack)
  429.       fputc('B',fh);
  430.      else
  431.       fputc('F',fh);
  432.      fputc('\n',fh);
  433.  
  434.      for (tn=GetHead(&ToolList); tn; tn=GetSucc(tn))
  435.       {
  436.        /* Write tool type */
  437.        switch(tn->tn_Type)
  438.         {
  439.          case TNTYPE_DUMMY:
  440.           fputs(DummyKey,fh);
  441.           break;
  442.          case TNTYPE_CLI:
  443.           fputs(CLIKey,fh);
  444.           break;
  445.          case TNTYPE_WB:
  446.           fputs(WBKey,fh);
  447.           break;
  448.         }
  449.        fputc('\n',fh);
  450.  
  451.        /* Write alias name */
  452.        WriteConfigLine(AliasKey,tn->tn_Node.ln_Name,fh);
  453.  
  454.        /* Write real name */
  455.        if (tn->tn_RealName)
  456.         WriteConfigLine(RealKey,tn->tn_RealName,fh);
  457.  
  458.        /* Write working directory */
  459.        if (tn->tn_WorkDir)
  460.         WriteConfigLine(DirKey,tn->tn_WorkDir,fh);
  461.  
  462.        /* Write path string */
  463.        if (tn->tn_Path)
  464.         WriteConfigLine(PathKey,tn->tn_Path,fh);
  465.  
  466.        /* Write stack size */
  467.        if (tn->tn_Stack>STACKMIN)
  468.         {
  469.          WriteParamKey(StackKey,fh);
  470.          ltoa(number,tn->tn_Stack);
  471.          fputs(number,fh);
  472.          fputc('\n',fh);
  473.         }
  474.  
  475.        /* Write argument passing state */
  476.        if (tn->tn_Flags&TNFLAGS_NARG)
  477.         WriteConfigLine(ArgsKey,OffKey,fh);
  478.  
  479.        /* Write output file state */
  480.        if (tn->tn_Flags&TNFLAGS_COUT)
  481.         if (tn->tn_OutFile)
  482.          WriteConfigLine(OFileKey,tn->tn_OutFile,fh);
  483.         else
  484.          WriteConfigLine(OutputKey,OnKey,fh);
  485.  
  486.        /* Write Workbench to front state */
  487.        if (tn->tn_Flags&TNFLAGS_WBTF)
  488.         WriteConfigLine(WBFrontKey,OnKey,fh);
  489.  
  490.        /* Write menu entry status */
  491.        if (!(tn->tn_Flags&TNFLAGS_MENU))
  492.         WriteConfigLine(MenuKey,OffKey,fh);
  493.  
  494.        /* Write HotKey description */
  495.        if (tn->tn_HotKey)
  496.         WriteConfigLine(HotKKey,tn->tn_HotKey,fh);
  497.  
  498.        /* Write icon stuff */
  499.        if (tn->tn_Flags&TNFLAGS_ICON)
  500.         {
  501.          if (tn->tn_Flags&TNFLAGS_NNAM)
  502.           WriteConfigLine(NameKey,OffKey,fh);
  503.  
  504.          if (!(tn->tn_Flags&TNFLAGS_DOBJ))
  505.           WriteConfigLine(ITypeKey,BrushKey,fh);
  506.  
  507.          if (tn->tn_IconFile)
  508.           WriteConfigLine(IFileKey,tn->tn_IconFile,fh);
  509.  
  510.          if ((tn->tn_Icon->do_CurrentX!=NO_ICON_POSITION) ||
  511.              (tn->tn_Icon->do_CurrentY!=NO_ICON_POSITION))
  512.           {
  513.            WriteParamKey(IPosKey,fh);
  514.            ltoa(number,tn->tn_Icon->do_CurrentX);
  515.            fputs(number,fh);
  516.            fputc(',',fh);
  517.            ltoa(number,tn->tn_Icon->do_CurrentY);
  518.            fputs(number,fh);
  519.            fputc('\n',fh);
  520.           }
  521.         }
  522.  
  523.        /* Write dock stuff */
  524.        if (tn->tn_Flags&TNFLAGS_DOCK)
  525.         if (tn->tn_Flags&TNFLAGS_SICN) WriteConfigLine(SIconKey,OnKey,fh);
  526.         else if (tn->tn_DockFile)
  527.               {
  528.                WriteConfigLine(DFileKey,tn->tn_DockFile,fh);
  529.                if (!(tn->tn_Flags&TNFLAGS_DDOB))
  530.                 WriteConfigLine(DTypeKey,BrushKey,fh);
  531.               }
  532.         else WriteConfigLine(DockOnKey,OnKey,fh);
  533.  
  534.        fputc(CONFIGBLOCKEND,fh);     /* Append config entry terminator */
  535.        fputc('\n',fh);               /* Append a new line */
  536.       }
  537.  
  538.      fclose(fh);                      /* Close the config file */
  539.      ConfigChanged=FALSE;             /* Config saved */
  540.      rc=FALSE;                        /* All OK */
  541.     }
  542.    else error=TRUE; /* Couldn't open file */
  543.  
  544.    if (!noreq) free(cp); /* free buffer from ShowFileRequester */
  545.   }
  546.  
  547. wce0: if (error) DisplayBeep(NULL);
  548.       return(rc);
  549. }
  550.